home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-17 | 8.2 KB | 325 lines | [TEXT/CWIE] |
- // Program Author: Paul Baxter
- // pbaxter@assistivetech.com
- //
- //
- // Sorry about all the 68k assembler code :-/
- // .....But the ADB Manager is fried
-
- #include <DeskBus.h>
- #include <Speech.h>
- #include <LowMem.h>
- #include <Retrace.h>
-
- #include "adb.h"
- #include "speech.h"
- #include "pref.h"
- #include "globals.h"
- #include "DeferredTask.h"
-
- #if GENERATING68K
- asm void ADBServiceWrapper(void);
- #if !TARGET_RT_MAC_CFM
- asm void CallADBServiceRoutineProc(ADBServiceRoutineUPP serviceRoutinePtr, Ptr buffer,
- TempADBServiceRoutineUPP completionProc, long refCon, long command);
-
- asm void MyADBInitProcGlue(SInt8 callOrder:__D0);
-
- #endif
- #endif
-
- extern ADBInitUPP JADBProc : 0x06B8; // where is this defined??
-
- static ADBInitUPP gOldADBInitProc = nil;
- static ADBDataBlock gKeyBoardADBData = { 0, 0, 0, 0 };
-
- #define kShiftCode 0x38
-
- // * ****************************************************************************** *
- // * ADBKeyBoardServiceRoutine
- // *
- // * By using this we are guaranteed not to miss any keystrokes
- // *
- // * This routine is called at interupt time and may not move memory!
- // * We can not call SpeakText here
- // * Do not use Debug() here!!! You can not use the keyboard!
- // * ****************************************************************************** *
- pascal void ADBKeyBoardServiceRoutine(Ptr buffer, TempADBServiceRoutineUPP completionProc, long refCon, long command)
- {
- ADBServiceRoutineUPP service;
- short count;
- unsigned char ch, state;
-
- // get our globals
- EnterAppCallBack();
-
- // make a local copy of service routine pointer
- service = gKeyBoardADBData.dbServiceRtPtr;
-
- // buffer[0] = length -- always 2 for the keyboard
- // buffer[1] = -1 no data or hi bit set for up the rest is the key code
- // buffer[2] = -1 no data or hi bit set for up the rest is the key code
-
-
- for (count = 1; count <= buffer[0]; count++) {
- if ((buffer[count] != -1)) { // -1 means there is no char available
-
- state = buffer[count] & kDepressedMask;
- ch = buffer[count] & kKeyCodeMask;
-
- if (ch == kShiftCode) // check state of shift key
- gShiftState = state == kDownState;
-
- if (state == kDownState) {
- AppendCharBuffer(ch); // save the char
- }
- // Power key gets sent twice
- if (ch == kPowerKey)
- break;
- }
- }
-
- InstallDeferredTask();
- // call the original handler so the keyboard still functions
- if (service)
- CallADBServiceRoutineProc(service, buffer, completionProc, refCon, command);
-
- // restore a5
- ExitAppCallBack();
- }
-
- // * ****************************************************************************** *
- // * InstallADBServiceRoutine
- // * Install our keyboard ADBHandler
- // * ****************************************************************************** *
- OSErr InstallADBServiceRoutine(ADBAddress adbaddr)
- {
- ADBSetInfoBlock adbsetinfo;
- OSErr err;
-
- err = noErr;
- if ((**gPrefs).speakChars) {
- err = GetADBInfo(&gKeyBoardADBData, adbaddr);
- if (!err) {
- adbsetinfo.siService = gKeyBoardServiceRoutine;
- adbsetinfo.siDataAreaAddr = gKeyBoardADBData.dbDataAreaAddr;
- err = SetADBInfo(&adbsetinfo, adbaddr);
- }
- }
- return err;
- }
-
- // * ****************************************************************************** *
- // * RemoveADBServiceRoutine
- // * Restore the original keyboard ADBhandler
- // * ****************************************************************************** *
- void RemoveADBServiceRoutine(ADBAddress adbaddr)
- {
- ADBSetInfoBlock adbsetinfo;
- OSErr err;
-
- if (gKeyBoardADBData.dbServiceRtPtr) {
-
- adbsetinfo.siService = gKeyBoardADBData.dbServiceRtPtr;
- adbsetinfo.siDataAreaAddr = gKeyBoardADBData.dbDataAreaAddr;
- err = SetADBInfo(&adbsetinfo, adbaddr);
- }
- }
-
- // * ****************************************************************************** *
- // * MyADBInitProc
- // * needed to re-install our service routine
- // * ****************************************************************************** *
- pascal void MyADBInitProc(short callOrder)
- {
- OSErr err;
-
- // get our globals
- EnterAppCallBack();
-
- CallADBInitProc(gOldADBInitProc, callOrder);
- if (callOrder != 0) {
- err = InstallADBServiceRoutine(gKeyBoardADBAddress);
- }
-
- // restore a5
- ExitAppCallBack();
- }
-
- // * ****************************************************************************** *
- // * InstallJADBProc
- // * Install a JADBProc callback for before and after ADBReInit
- // * ****************************************************************************** *
- void InstallJADBProc(void)
- {
- ADBInitUPP ourADBInitProc;
- THz theZone;
-
- theZone = GetZone();
- SetZone(SystemZone());
- gOldADBInitProc = JADBProc;
- #if GENERATING68K
- ourADBInitProc = (ADBInitUPP) MyADBInitProcGlue;
- #else
- ourADBInitProc = NewADBInitProc(MyADBInitProc);
- #endif
- SetZone(theZone);
- JADBProc = ourADBInitProc;
- }
-
- // * ****************************************************************************** *
- // * UInstallJADBProc
- // * Remove JADBProc
- // * ****************************************************************************** *
- void UnInstallJADBProc(void)
- {
- if (gOldADBInitProc)
- JADBProc = gOldADBInitProc;
- }
-
- // * ****************************************************************************** *
- // * InitADBService
- // * Init the ADBServieRoutine for the keyboard
- // * ****************************************************************************** *
- void InitADBService(void)
- {
- THz theZone;
-
- theZone = GetZone();
- SetZone(SystemZone());
- // allocate adbservice routine
- #if GENERATING68K
- if (!gKeyBoardServiceRoutine)
- gKeyBoardServiceRoutine = NewADBServiceRoutineProc(ADBServiceWrapper);
- #else
- if (!gKeyBoardServiceRoutine)
- gKeyBoardServiceRoutine = NewADBServiceRoutineProc(ADBKeyBoardServiceRoutine);
- #endif
- if (!gOldADBInitProc)
- gOldADBInitProc = JADBProc;
-
- SetZone(theZone);
- }
-
- // * ****************************************************************************** *
- // * InitADBAddress
- // * Init the original keyboard address MUST BE CALLED FIRST
- // * ****************************************************************************** *
- Boolean InitADBAddress(void)
- {
- ADBDataBlock adbinfo;
- ADBAddress addr;
- short adbcount, adbindex;
-
- // see if we can find the keyboard ADBaddress
- adbcount = CountADBs();
- for (adbindex = 1; adbindex <= adbcount; adbindex++) {
- addr = GetIndADB(&adbinfo, adbindex);
- if (addr >= 0) {
- if (adbinfo.origADBAddr == kKeyBoardAddr) {
- gKeyBoardADBAddress = addr;
- return true;
- }
- }
- }
- return false;
- }
-
- // * ****************************************************************************** *
- // * ADBServiceWrapper
- // * Wrapper for 68K ServiceRoutine .. Just call the C version
- // * ****************************************************************************** *
- #if GENERATING68K
- asm void ADBServiceWrapper(void)
- {
- fralloc
-
- // This bombs if we set A5
- // why ????
-
- // AsmEnterAppCallBack
-
- move.l A0,-(sp)
- move.l A1,-(sp)
- move.l A2,-(sp)
- move.l D0,-(sp)
- jsr ADBKeyBoardServiceRoutine
- add.l #16,SP
-
- // AsmExitAppCallBack
-
- frfree
-
- rts
- }
-
- // * ****************************************************************************** *
- // * CallADBServiceRoutineProc
- // * Why this isn't in a glue lib is beyond me.
- // * ****************************************************************************** *
- #if !TARGET_RT_MAC_CFM
- asm void CallADBServiceRoutineProc(ADBServiceRoutineUPP serviceRoutinePtr, Ptr buffer,
- TempADBServiceRoutineUPP completionProc, long refCon, long command)
- {
-
- fralloc
-
- AsmEnterAppCallBack
-
- movem.l A0-A3/D0-D3, -(SP)
-
- movea.l buffer, A0
- movea.l completionProc, A1
- movea.l refCon, A2
- move.l command, D0
-
- // very strange bug
- //
- // jsr serviceRoutinePtr
- //
- // causes a crash
- // we must put it into an address register
- // and then jsr to it
- movea.l serviceRoutinePtr, A3
- jsr (A3)
-
- movem.l (SP)+,A0-A3/D0-D3
-
- AsmExitAppCallBack
-
- frfree
-
- rts
- }
-
- // * ****************************************************************************** *
- // * MyADBInitProcGlue
- // * This also should be a glue routine
- // * ****************************************************************************** *
- asm void MyADBInitProcGlue(SInt8 callOrder:__D0)
- {
- AsmEnterAppCallBack
-
- movem.l d0,-(sp)
- move.l gOldADBInitProc,a0
- jsr (a0)
- movem.l (sp)+,d0
-
- tst.b d0
- beq.s @done
-
- clr.w -(sp)
- move.w gKeyBoardADBAddress,-(sp)
- jsr InstallADBServiceRoutine
- move.w (sp)+,d0
- addq.l #2,sp
-
- @done:
-
- AsmExitAppCallBack
-
- rts
- }
-
- #endif
- #endif
-